<template>
  <div 
    v-if="visible" 
    class="fixed inset-0 flex items-center justify-center z-50"
    @click="handleBackdropClick"
  >
    <div class="absolute inset-0 bg-black bg-opacity-50 backdrop-blur-sm"></div>
    <div 
      class="bg-white rounded-lg shadow-xl relative z-10 transform transition-all duration-300"
      :class="[sizeClasses, visible ? 'scale-100 opacity-100' : 'scale-95 opacity-0']"
      @click.stop
    >
      <!-- 标题栏 -->
      <div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center">
        <h3 class="text-lg font-medium text-gray-900">{{ title }}</h3>
        <div class="flex items-center space-x-3">
          <slot name="header-actions"></slot>
          <button 
            @click="close"
            class="text-gray-400 hover:text-gray-500 transition-colors"
            :class="{ 'hidden': !showClose }"
          >
            <i class="fas fa-times"></i>
          </button>
        </div>
      </div>
      
      <!-- 内容区域 -->
      <div class="px-6 py-4 flex-1 overflow-auto" :class="{ 'max-h-96': scrollable }">
        <slot></slot>
      </div>
      
      <!-- 底部操作栏 -->
      <div v-if="$slots.footer" class="px-6 py-4 border-t border-gray-200 flex justify-end space-x-3">
        <slot name="footer"></slot>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, watch } from 'vue'

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  title: {
    type: String,
    default: ''
  },
  size: {
    type: String,
    default: 'md', // 'sm', 'md', 'lg', 'xl'
    validator: (value) => ['sm', 'md', 'lg', 'xl'].includes(value)
  },
  showClose: {
    type: Boolean,
    default: true
  },
  closeOnBackdrop: {
    type: Boolean,
    default: true
  },
  scrollable: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['update:visible', 'close'])

const sizeClasses = computed(() => {
  const sizes = {
    sm: 'w-[400px] max-w-sm',
    md: 'w-[600px] max-w-2xl',
    lg: 'w-[700px] max-w-4xl',
    xl: 'w-[900px] max-w-6xl'
  }
  return sizes[props.size] + ' max-h-[80vh] flex flex-col'
})

const close = () => {
  emit('update:visible', false)
  emit('close')
}

const handleBackdropClick = () => {
  if (props.closeOnBackdrop) {
    close()
  }
}

// 监听ESC键关闭模态框
watch(() => props.visible, (newVal) => {
  if (newVal) {
    document.addEventListener('keydown', handleEscape)
    document.body.style.overflow = 'hidden'
  } else {
    document.removeEventListener('keydown', handleEscape)
    document.body.style.overflow = ''
  }
})

const handleEscape = (e) => {
  if (e.key === 'Escape' && props.visible) {
    close()
  }
}
</script>
